package org.stvd.controller.admin;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.stvd.common.Consts;
import org.stvd.common.aspectj.lang.annotation.Log;
import org.stvd.common.aspectj.lang.enums.BusinessType;
import org.stvd.common.enums.UserLoginTypeEnum;
import org.stvd.common.security.SecurityUserHolder;
import org.stvd.common.utils.InterfaceResult;
import org.stvd.common.utils.PwdUtil;
import org.stvd.controller.BaseController;
import org.stvd.core.util.DateUtil;
import org.stvd.core.util.StringUtil;
import org.stvd.entities.admin.Department;
import org.stvd.entities.admin.Guids;
import org.stvd.entities.admin.Roles;
import org.stvd.entities.admin.UserBase;
import org.stvd.entities.admin.UserLogin;
import org.stvd.entities.admin.Users;
import org.stvd.service.admin.DepartmentService;
import org.stvd.service.admin.GuidsService;
import org.stvd.service.admin.RolesService;
import org.stvd.service.admin.UserBaseService;
import org.stvd.service.admin.UsersService;
import org.stvd.service.common.CommonService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;

/**
 * 系统用户-控制类
 * @author houzx
 */
@Api(tags= "系统用户接口类")
@Controller
@RequestMapping("/admin/users")
public class UsersController extends BaseController {

    @Autowired
    RolesService rolesService;
    @Autowired
    UsersService usersService;
    @Autowired
    DepartmentService departmentService;
    @Autowired
    UserBaseService userBaseService;
    @Autowired
    private GuidsService guidsService;
    @Autowired
    private CommonService commonService;
    
    private String tmpURL = "/admin/users/";

    /**
     * 用户管理请求
     * @param users
     * @return
     */
    @ApiIgnore
    @GetMapping(value = "management")
    public String onUserManageLoad(@ModelAttribute("users") Users users) {
        if(!StringUtil.isEmpty(request.getParameter("gid"))) {
            users.setGuid(request.getParameter("gid"));
        }
        if(StringUtil.isEmpty(users.getGuid())) { 
            users.setGuid(Consts.GUID);
        }
        loadUserResources(users);
        return tmpURL + "UsersManagement.html";
    }
    
    @ApiIgnore
    @PostMapping(value = "management")
    public String onUserManageAction(@ModelAttribute("users") Users users) {
        loadUserResources(users);
        return tmpURL + "UsersManagement.html";
    }
    
    // 用户数据资源加载公用方法
    public void loadUserResources(Users users) {
        String userId = SecurityUserHolder.getCurrentUserId();
        boolean isManage = commonService.checkManage(userId, users.getGuid());
        List<Department> depList = null; // 机构下拉列表
        List<Department> serDepList = null; //机构检索列表
        List<Roles> roleList = null; //角色下拉列表
        if(isManage) {
            depList = departmentService.getFormatAllDepByGuid(users.getGuid());
            roleList = rolesService.findValidRolesByDepId(users.getDepId(), users.getGuid());
            if(StringUtil.isEmpty(users.getDepId())) {
                serDepList = depList;
            }else {
                serDepList = departmentService.getAllChildDepartment(users.getDepId(), users.getGuid());
            }
        }else{
            String depId = SecurityUserHolder.getCurrentMaxAuthDepId(users.getGuid());
            if (StringUtil.isEmpty(users.getDepId())) {
                users.setDepId(depId);
            }
            depList = departmentService.getAllChildDepartment(depId, users.getGuid());
            serDepList = depList;
            roleList = rolesService.findValidRolesByDepId(depId, users.getGuid());
        }
        List<String> depIds = new ArrayList<String>();
        if(serDepList!=null && serDepList.size() > 0) {
            for (Department department : serDepList) {
                depIds.add(department.getDepId());
            }
        }
        map.put("queryResult", usersService.getUsersQueryResult((pageNo - 1) * pageSize, pageSize, 
            users.getLoginAccount(), users.getUname(), depIds, users.getRoleId(), users.getGuid()));
        map.put("userDepList", departmentService.listUserDepByGuid(users.getGuid()));
        map.put("userRoleList", rolesService.listUserRolesByGuid(users.getGuid()));
        map.put("userAccountList", usersService.listAllUserLogin());
        map.put("guidsList", guidsService.listGuidByUserId(userId));
        map.put("guids", guidsService.findByPk(Guids.class, Consts.GUID));
        map.put("dep", SecurityUserHolder.getCurrentMaxAuthDep(Consts.GUID));
        map.put("depList", depList);
        map.put("roleList", roleList);
    }

    /**
     * 新增用户
     */
    @ApiIgnore
    @GetMapping(value = "add")
    public String onAddLoad(@ModelAttribute("users") Users users) {
        users.setGuid(Consts.GUID);
        map.put("users", users);
        Department department = SecurityUserHolder.getCurrentMaxAuthDep(Consts.GUID);
        if(department!=null) {
            map.put("guidList", guidsService.listGuidByUserId(SecurityUserHolder.getCurrentUserId()));
            map.put("depList", departmentService.getAllChildDepartment(department.getDepId(), Consts.GUID));
            map.put("roleList", rolesService.findValidRolesByDepId(department.getDepId(), Consts.GUID));
            map.put("dep", department);
        }
        return tmpURL + "UsersAdd.html";
    }

    @ApiOperation(value = "新增用户账号")
    @Log(title = "新增用户账号", businessType = BusinessType.INSERT)
    @PostMapping(value = "add")
    @ResponseBody
    public InterfaceResult<Map<String, Object>> onAddAction(
        @Valid @ModelAttribute("users") Users users, BindingResult bindingResult){
        InterfaceResult<Map<String, Object>> result = new InterfaceResult<Map<String,Object>>();
        if (bindingResult.hasErrors()) {
            result.setError(bindingResult.getAllErrors().get(0).getDefaultMessage());
            return result;
        }
        if (!users.getPwd().equals(users.getPwdConfirm())) {
            result.setError("两次输入的密码不一致！");
            return result;
        }
        String checkResult = PwdUtil.chechPwdStrength(users.getPwd(), users.getLoginAccount());
        if (checkResult != null) {
            result.setError(checkResult);
            return result;
        }
        UserLogin userLogin = usersService.findUserLoginByLoginAccount(users.getLoginAccount());
        if(userLogin!=null) {
            result.setError("当前账号已存在！");
            return result;
        }
        //用户拥有角色
        String[] roleIdArray = (users.getRoleId() != null) ? users.getRoleId().split(",") : null;
        //用户所属机构
        String[] depIdArray = (users.getDepId() != null) ? users.getDepId().split(",") : null;
        //用户权限平台
        String[] guidArray = (users.getGuid() != null) ? users.getGuid().split(",") : null;
        Date indate = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(indate);
        // 将时分秒,毫秒域清零
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        String ymd = DateUtil.Y2NO_FORMAT.format(calendar.getTime());
        String pwd = users.getPwd();
        String userId = StringUtil.getRandomUUID();
        //用户登录账号
        userLogin = new UserLogin();
        userLogin.setId(StringUtil.getRandomUUID());
        userLogin.setUserId(userId);
        userLogin.setLoginAccount(users.getLoginAccount());
        userLogin.setLoginType(UserLoginTypeEnum.UserCode.getValue());
        userLogin.setCreateTime(DateUtil.getSystemDate());
        userLogin.setCreateUser(SecurityUserHolder.getCurrentUserId());
        //用户基本信息
        UserBase userBase = new UserBase();
        userBase.setUserId(userId);
        userBase.setNickName(users.getUname());
        //用户安全账户
        users.setUserId(userId);
        users.setEnable("T");
        users.setIndate(calendar.getTime());
        users.setModifyDate(DateUtil.getSystemDate());
        users.setPwd(StringUtil.encrypt(pwd, users.getUserId() + ymd));
        try {
            usersService.insert(users, roleIdArray, depIdArray, guidArray, userLogin, userBase, Consts.GUID);
            result.setMsg("账户新增成功！");
        } catch (Exception e) {
            e.printStackTrace();
            result.setError("账户新增失败！失败原因：" + e.getMessage());
        }
        map.clear();
        return result;
    }

    /**
     * 修改用户信息
     */
    @ApiIgnore
    @GetMapping(value = "edit/{userId}")
    public String onEditLoad(@PathVariable String userId) {
        Users users = usersService.findById(userId);
        if(users!=null) {
            users.setPwdConfirm(users.getPwd());
            map.put("users", users);
            map.put("loginAccountList", usersService.findUserLoginByUserId(userId));
            map.put("guidList", guidsService.listGuidByUserId(SecurityUserHolder.getCurrentUserId()));
        }else {
            map.put("errorList", "获取用户信息失败，请返回重试！");
        }
        return tmpURL + "UsersEdit.html";
    }

    @ApiOperation(value="修改账号信息")
    @Log(title = "修改账号信息", businessType = BusinessType.UPDATE)
    @PostMapping(value = "edit")
    @ResponseBody
    public InterfaceResult<Map<String, Object>> onEditAction(
        @Valid @ModelAttribute("users") Users users, BindingResult bindingResult) {
        InterfaceResult<Map<String, Object>> result = new InterfaceResult<Map<String,Object>>();
        if (bindingResult.hasErrors()) {
            result.setError(bindingResult.getAllErrors().get(0).getDefaultMessage());
            return result;
        }
        String[] guidArray = (!StringUtil.isEmpty(users.getGuid())) ? users.getGuid().split(",") : null;
        users.setModifyDate(DateUtil.getSystemDate());
        usersService.update(users, guidArray);
        map.clear();
        result.setMsg("修改成功！");
        return result;
    }

    /**
     * 修改用户权限
     * @param userId
     * @return
     */
    @ApiIgnore
    @GetMapping(value = "auth/{userId}")
    public String onAuthLoad(@PathVariable String userId) {
        Users users = usersService.findByPk(Users.class, userId);
        if(users!=null) {
            users.setGuid(Consts.GUID);
            String depId = SecurityUserHolder.getCurrentMaxAuthDepId(Consts.GUID);
            map.put("guidsList", guidsService.listGuidByUserId(SecurityUserHolder.getCurrentUserId()));
            map.put("guids", guidsService.findByPk(Guids.class, Consts.GUID));
            map.put("depList", departmentService.getAllChildDepartment(depId, Consts.GUID));
            map.put("dep", SecurityUserHolder.getCurrentMaxAuthDep(Consts.GUID));
            List<Roles> roleList = rolesService.findValidRolesByDepId(depId, Consts.GUID);
            if(roleList!=null && roleList.size() > 0) {
                List<Roles> userRoleList = rolesService.getRolesByUserId(userId, Consts.GUID);
                if(userRoleList!=null && userRoleList.size() > 0) {
                    String userRoleIds = "";
                    for (Roles userRole : userRoleList) {
                        if(userRoleIds!="") {
                            userRoleIds +=",";
                        }
                        userRoleIds += userRole.getRoleId();
                    }
                    users.setRoleId(userRoleIds);
                }
            }
            map.put("roleList", roleList);
            map.put("users", users);
        }else {
            map.put("errorList", "获取用户信息失败，请返回重试！");
        }
        return tmpURL + "UsersAuth.html";
    }

    @ApiOperation(value = "修改用户权限")
    @Log(title = "修改用户权限", businessType = BusinessType.UPDATE)
    @PostMapping(value = "auth")
    @ResponseBody
    public InterfaceResult<Map<String, Object>> onAuthAction(@ModelAttribute("users") Users users) {
        InterfaceResult<Map<String, Object>> result = new InterfaceResult<Map<String,Object>>();
        String[] roleIdArray = (!StringUtil.isEmpty(users.getRoleId())) ? users.getRoleId().split(",") : null;
        String[] depIdArray = (!StringUtil.isEmpty(users.getDepId())) ? users.getDepId().split(",") : null;
        usersService.update(roleIdArray, depIdArray, users.getUserId(), users.getGuid());
        map.clear();
        result.setMsg("授权成功！");
        return result;
    }
    
    
    /**
     * 修改密码GET
     */
    @ApiIgnore
    @GetMapping(value = "editpwd")
    public String onEditPwdLoad() {
        Users users = new Users();
        users.setUserId(SecurityUserHolder.getCurrentUserInfo().getUserId());
        users.setUname(SecurityUserHolder.getCurrentUserInfo().getUname());
        users.setEnable(SecurityUserHolder.getCurrentUserInfo().getEnable());
        users.setIndate(SecurityUserHolder.getCurrentUserInfo().getIndate());
        users.setModifyDate(SecurityUserHolder.getCurrentUserInfo().getModifyDate());
        users.setLastDate(SecurityUserHolder.getCurrentUserInfo().getLastDate());
        users.setLogintimes(SecurityUserHolder.getCurrentUserInfo().getLogintimes());
        map.put("users", users);
        return tmpURL + "PasswordEdit.html";
    }

    @ApiOperation(value = "修改用户密码")
    @Log(title = "修改用户密码", businessType = BusinessType.UPDATE)
    @PostMapping(value = "editpwd")
    @ResponseBody
    public InterfaceResult<Map<String, Object>> onEditPwdAction(
        @Valid @ModelAttribute("users") Users users, BindingResult bindingResult) {
        InterfaceResult<Map<String, Object>> result = new InterfaceResult<Map<String,Object>>();
        if (bindingResult.hasErrors()) {
            result.setError(bindingResult.getAllErrors().get(0).getDefaultMessage());
            return result;
        }
        String userid = SecurityUserHolder.getCurrentUserInfo().getUserId();
        if ("1".equals(checkPWD(userid, users.getOldPwd()).getCode())) {
            result.setError("原密码输入不正确！");
            return result;
        }
        if (!users.getPwd().equals(users.getPwdConfirm())) {
            result.setError("两次输入的密码不一致！");
            return result;
        }
        String checkResult = PwdUtil.chechPwdStrength(users.getPwd(), users.getLoginAccount());
        if (checkResult != null) {
            result.setError(checkResult);
            return result;
        }
        try {
            usersService.updatePwd(userid,
                StringUtil.encrypt(users.getOldPwd(), userid + DateUtil.Y2NO_FORMAT.format(users.getIndate())),
                StringUtil.encrypt(users.getPwdConfirm(), userid + DateUtil.Y2NO_FORMAT.format(users.getIndate())));
            result.setMsg("修改成功！");
        } catch (Exception e) {
            e.printStackTrace();
            result.setError("修改失败！失败原因："+e.getMessage());
        }
        map.clear();
        return result;
    }

    /**
     * 禁用用户
     */
    @ApiOperation(value = "禁用用户账号")
    @Log(title = "禁用用户账号", businessType = BusinessType.UPDATE)
    @PostMapping(value = "disable")
    @ResponseBody
    public InterfaceResult<Map<String, Object>> onDisabled(String userId) {
        InterfaceResult<Map<String, Object>> result = new InterfaceResult<Map<String,Object>>();
        try {
            if (userId.equals(SecurityUserHolder.getCurrentUserId())) {
                result.setError("禁用用户失败！<br/>失败原因：不能禁用自己！");
            } else {
                usersService.changeUserStatus(userId, "F");
                result.setMsg("禁用用户成功！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            result.setError("禁用用户失败！<br/>失败原因：" + e.getMessage());
        }
        return result;
    }
    /**
     * 启用用户
     */
    @ApiOperation(value = "启用用户账号")
    @Log(title = "启用用户账号", businessType = BusinessType.UPDATE)
    @PostMapping(value = "enable")
    @ResponseBody
    public InterfaceResult<Map<String, Object>> onEnabled(String userId) {
        InterfaceResult<Map<String, Object>> result = new InterfaceResult<Map<String,Object>>();
        try {
            usersService.changeUserStatus(userId, "T");
            result.setMsg("启用用户成功！");
        } catch (Exception e) {
            e.printStackTrace();
            result.setError("启用用户失败！<br/>失败原因：" + e.getMessage());
        }
        return result;
    }
    
    /**
     * 验证用户密码
     */
    @ApiOperation(value = "验证用户密码")
    @PostMapping(value = "checkpwd")
    @ResponseBody
    public InterfaceResult<Map<String, Object>> checkPWD(String userId, String password) {
        InterfaceResult<Map<String, Object>> result = new InterfaceResult<Map<String,Object>>();
        try {
            String pwdTmp = password;
            Users user = this.usersService.findByPk(Users.class, userId);
            if (user != null) {
                pwdTmp = StringUtil.encrypt(pwdTmp, userId + DateUtil.Y2NO_FORMAT.format(user.getIndate()));
                if (user.getPwd().equals(pwdTmp)) {
                    result.setMsg("密码验证成功！");
                } else {
                    result.setError("密码验证失败！<br/>密码不正确！");
                }
            } else {
                result.setError("密码验证失败！<br/>用户信息不存在！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            result.setError("密码验证失败！<br/>失败原因：" + e.getMessage());
        }
        return result;

    }

    /**
     * 密码还原
     */
    @ApiOperation(value = "重置用户密码")
    @Log(title = "重置用户密码", businessType = BusinessType.UPDATE)
    @PostMapping(value = "clrpwd")
    @ResponseBody
    public InterfaceResult<Map<String, Object>> onclrPwd(String userId, String guid) {
        InterfaceResult<Map<String, Object>> result = new InterfaceResult<Map<String,Object>>();
        try {
            result.setMsg(usersService.clrPwd(userId, guid));
        } catch (Exception e) {
            e.printStackTrace();
            result.setError("密码还原失败！<br/>失败原因：" + e.getMessage());
        }
        return result;
    }
    
    /**
     * 账号注销
     */
    @ApiOperation(value = "注销用户账号")
    @Log(title = "注销用户账号", businessType = BusinessType.DELETE)
    @PostMapping(value = "del")
    @ResponseBody
    public InterfaceResult<Map<String, Object>> onclrPwd(String userId) {
        InterfaceResult<Map<String, Object>> result = new InterfaceResult<Map<String,Object>>();
        try {
            result.transferResult(usersService.delUser(userId));
        } catch (Exception e) {
            e.printStackTrace();
            result.setError("账号注销失败！<br/>失败原因：" + e.getMessage());
        }
        return result;
    }
}
